class EnhancedAudioAnalyzer extends StreamingAudioAnalyzer {
    constructor() {
        super();
        this.currentMode = 'local';
        this.audioElement = null;
        this.performanceConfig = 'medium';
        
        // UI元素
        this.canvas = document.getElementById('canvas');
        this.ctx = this.canvas.getContext('2d');
        this.progressBar = document.getElementById('progressBar');
        this.status = document.getElementById('status');
        this.fileInfo = document.getElementById('fileInfo');
        this.performanceInfo = document.getElementById('performanceInfo');
        
        // 模式按钮
        this.localModeBtn = document.getElementById('localMode');
        this.streamModeBtn = document.getElementById('streamMode');
        this.externalModeBtn = document.getElementById('externalMode');
        
        // 控制按钮
        this.loadBtn = document.getElementById('loadBtn');
        this.playBtn = document.getElementById('playBtn');
        this.pauseBtn = document.getElementById('pauseBtn');
        this.stopBtn = document.getElementById('stopBtn');
        this.analyzeBtn = document.getElementById('analyzeBtn');
        this.exportBtn = document.getElementById('exportBtn');
        
        // 输入元素
        this.audioFileInput = document.getElementById('audioFile');
        this.streamUrlInput = document.getElementById('streamUrl');
        this.spectrumUrlInput = document.getElementById('spectrumUrl');
        this.audioFileExtInput = document.getElementById('audioFileExt');
        this.spectrumFileInput = document.getElementById('spectrumFile');
        
        // 设置元素
        this.qualityLevelSelect = document.getElementById('qualityLevel');
        this.compressionTypeSelect = document.getElementById('compressionType');
        this.useWebWorkerSelect = document.getElementById('useWebWorker');
        
        this.initializeCanvas();
        this.bindEvents();
        this.updateStatus('请选择模式和音频来源...');
    }

    initializeCanvas() {
        const resizeCanvas = () => {
            const rect = this.canvas.getBoundingClientRect();
            this.canvas.width = rect.width * window.devicePixelRatio;
            this.canvas.height = rect.height * window.devicePixelRatio;
            this.ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
        };
        
        resizeCanvas();
        window.addEventListener('resize', resizeCanvas);
    }

    bindEvents() {
        // 模式切换
        this.localModeBtn.addEventListener('click', () => this.switchMode('local'));
        this.streamModeBtn.addEventListener('click', () => this.switchMode('stream'));
        this.externalModeBtn.addEventListener('click', () => this.switchMode('external'));
        
        // 控制按钮
        this.loadBtn.addEventListener('click', () => this.loadAudio());
        this.playBtn.addEventListener('click', () => this.play());
        this.pauseBtn.addEventListener('click', () => this.pause());
        this.stopBtn.addEventListener('click', () => this.stop());
        this.analyzeBtn.addEventListener('click', () => this.analyzeSpectrum());
        this.exportBtn.addEventListener('click', () => this.exportSpectrum());
        
        // 设置变更
        this.qualityLevelSelect.addEventListener('change', (e) => {
            this.optimizePerformance(e.target.value);
            this.updatePerformanceInfo();
        });
        
        this.compressionTypeSelect.addEventListener('change', () => {
            this.updatePerformanceInfo();
        });
        
        this.useWebWorkerSelect.addEventListener('change', (e) => {
            this.useWebWorker = e.target.value === 'true';
            if (this.useWebWorker && !this.spectrumWorker) {
                this.createSpectrumWorker();
            }
        });
    }

    switchMode(mode) {
        this.currentMode = mode;
        
        // 更新按钮状态
        document.querySelectorAll('.mode-btn').forEach(btn => btn.classList.remove('active'));
        document.getElementById(mode + 'Mode').classList.add('active');
        
        // 显示/隐藏输入区域
        document.querySelectorAll('.input-mode').forEach(el => el.classList.add('hidden'));
        document.getElementById(mode + 'Inputs').classList.remove('hidden');
        
        // 重置状态
        this.resetAnalyzer();
        this.updateStatus(`已切换到${this.getModeDisplayName(mode)}模式`);
    }

    getModeDisplayName(mode) {
        const names = {
            'local': '本地文件',
            'stream': '网络流媒体',
            'external': '外部频谱文件'
        };
        return names[mode] || mode;
    }

    async loadAudio() {
        this.updateStatus('正在加载...', 'loading');
        this.loadBtn.disabled = true;
        
        try {
            switch (this.currentMode) {
                case 'local':
                    await this.loadLocalFile();
                    break;
                case 'stream':
                    await this.loadStreamAudio();
                    break;
                case 'external':
                    await this.loadExternalSpectrum();
                    break;
            }
        } catch (error) {
            console.error('加载失败:', error);
            this.updateStatus('加载失败: ' + error.message, 'error');
        } finally {
            this.loadBtn.disabled = false;
        }
    }

    async loadLocalFile() {
        const file = this.audioFileInput.files[0];
        if (!file) {
            throw new Error('请选择一个音频文件');
        }

        if (!this.audioContext) {
            this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
        }

        const arrayBuffer = await file.arrayBuffer();
        this.audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);
        
        this.displayFileInfo(file, this.audioBuffer);
        this.enableControls();
        this.updateStatus('本地文件加载成功！可以播放或分析频谱。', 'success');
        
        // 检查缓存
        this.checkCachedSpectrum(file.name);
    }

    async loadStreamAudio() {
        const streamUrl = this.streamUrlInput.value.trim();
        const spectrumUrl = this.spectrumUrlInput.value.trim();
        
        if (!streamUrl) {
            throw new Error('请输入音频流URL');
        }

        this.isStreamMode = true;
        
        // 加载外部频谱文件（如果提供）
        if (spectrumUrl) {
            const result = await super.loadExternalSpectrum(spectrumUrl, streamUrl);
            if (!result.success) {
                console.warn('外部频谱加载失败，将使用实时分析');
            }
        }
        
        // 处理音频流
        const result = await this.handleAudioStream(streamUrl);
        if (!result.success) {
            throw new Error('音频流加载失败');
        }
        
        this.audioElement = result.audio;
        this.enableControls();
        this.updateStatus('音频流加载成功！正在进行实时分析。', 'success');
    }

    async loadExternalSpectrum() {
        const audioFile = this.audioFileExtInput.files[0];
        const spectrumFile = this.spectrumFileInput.files[0];
        
        if (!audioFile || !spectrumFile) {
            throw new Error('请同时选择音频文件和频谱文件');
        }

        // 加载音频文件
        if (!this.audioContext) {
            this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
        }

        const arrayBuffer = await audioFile.arrayBuffer();
        this.audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);
        
        // 加载频谱文件
        const spectrumBlob = new Blob([spectrumFile]);
        const spectrumUrl = URL.createObjectURL(spectrumBlob);
        
        const response = await fetch(spectrumUrl);
        const spectrumData = await this.parseSpectrumFile(response);
        this.externalSpectrumData = spectrumData;
        this.cachedSpectrumData = spectrumData.frames;
        
        this.displayFileInfo(audioFile, this.audioBuffer);
        this.enableControls();
        this.updateStatus(`外部频谱文件加载成功！共 ${spectrumData.frames.length} 帧数据。`, 'success');
        
        URL.revokeObjectURL(spectrumUrl);
    }

    enableControls() {
        this.playBtn.disabled = false;
        this.analyzeBtn.disabled = this.currentMode === 'external'; // 外部模式不需要分析
        this.exportBtn.disabled = false;
    }

    displayFileInfo(file, audioBuffer) {
        const duration = audioBuffer.duration.toFixed(2);
        const sampleRate = audioBuffer.sampleRate;
        const channels = audioBuffer.numberOfChannels;
        const size = (file.size / 1024 / 1024).toFixed(2);
        
        this.fileInfo.innerHTML = `
            <strong>📁 文件信息：</strong><br>
            🎵 文件名: ${file.name}<br>
            ⏱️ 时长: ${duration}秒<br>
            🔊 采样率: ${sampleRate}Hz<br>
            📡 声道数: ${channels}<br>
            💾 文件大小: ${size}MB<br>
            🎯 模式: ${this.getModeDisplayName(this.currentMode)}
        `;
    }

    checkCachedSpectrum(fileName) {
        const cacheKey = `spectrum_${fileName}`;
        const cached = localStorage.getItem(cacheKey);
        if (cached) {
            this.cachedSpectrumData = JSON.parse(cached);
            this.updateStatus('发现缓存的频谱数据，播放时将使用增强动画！');
        }
    }

    async play() {
        if (this.isStreamMode && this.audioElement) {
            // 流媒体播放
            await this.audioElement.play();
            this.isPlaying = true;
            this.updatePlayingState();
            this.startVisualization();
        } else if (this.audioBuffer) {
            // 本地文件播放
            await this.playLocalAudio();
        }
    }

    async playLocalAudio() {
        if (!this.audioBuffer) return;

        try {
            if (this.audioContext.state === 'suspended') {
                await this.audioContext.resume();
            }

            this.stop();

            this.source = this.audioContext.createBufferSource();
            this.source.buffer = this.audioBuffer;

            this.analyser = this.audioContext.createAnalyser();
            this.analyser.fftSize = 2048;
            this.analyser.smoothingTimeConstant = 0.8;

            this.source.connect(this.analyser);
            this.analyser.connect(this.audioContext.destination);

            this.frequencyData = new Uint8Array(this.analyser.frequencyBinCount);

            const offset = this.isPaused ? this.pausedTime : 0;
            this.startTime = this.audioContext.currentTime - offset;
            this.source.start(0, offset);

            this.isPlaying = true;
            this.isPaused = false;
            this.updatePlayingState();
            this.startVisualization();

            this.source.onended = () => {
                if (this.isPlaying) {
                    this.stop();
                }
            };

            this.updateStatus('正在播放...');

        } catch (error) {
            console.error('播放失败:', error);
            this.updateStatus('播放失败', 'error');
        }
    }

    pause() {
        if (this.isStreamMode && this.audioElement) {
            this.audioElement.pause();
        } else if (this.source) {
            this.source.stop();
            this.pausedTime = this.audioContext.currentTime - this.startTime;
        }
        
        this.isPlaying = false;
        this.isPaused = true;
        this.updatePausedState();
        this.stopVisualization();
        this.updateStatus('已暂停');
    }

    stop() {
        if (this.isStreamMode && this.audioElement) {
            this.audioElement.pause();
            this.audioElement.currentTime = 0;
        } else if (this.source) {
            this.source.stop();
            this.source = null;
        }

        this.isPlaying = false;
        this.isPaused = false;
        this.pausedTime = 0;
        this.updateStoppedState();
        this.stopVisualization();
        this.progressBar.style.width = '0%';
        this.updateStatus('已停止');
    }

    updatePlayingState() {
        this.playBtn.disabled = true;
        this.pauseBtn.disabled = false;
        this.stopBtn.disabled = false;
    }

    updatePausedState() {
        this.playBtn.disabled = false;
        this.pauseBtn.disabled = true;
        this.stopBtn.disabled = false;
    }

    updateStoppedState() {
        this.playBtn.disabled = false;
        this.pauseBtn.disabled = true;
        this.stopBtn.disabled = true;
    }

    async analyzeSpectrum() {
        if (this.currentMode === 'external') return;
        
        this.updateStatus('正在进行频谱分析...', 'loading');
        this.analyzeBtn.disabled = true;

        try {
            const format = 'binary';
            const compression = this.compressionTypeSelect.value;
            const blob = await this.generateSpectrumFile(this.audioBuffer, format, compression);
            
            // 解析生成的数据作为缓存
            const arrayBuffer = await blob.arrayBuffer();
            const response = new Response(arrayBuffer);
            const spectrumData = await this.parseSpectrumFile(response);
            
            this.cachedSpectrumData = spectrumData.frames;
            
            // 缓存到localStorage
            const fileName = this.audioFileInput.files[0]?.name || 'stream_audio';
            const cacheKey = `spectrum_${fileName}`;
            localStorage.setItem(cacheKey, JSON.stringify(spectrumData.frames));
            
            this.updateStatus(`频谱分析完成！共 ${spectrumData.frames.length} 帧数据已缓存。`, 'success');
            
        } catch (error) {
            console.error('频谱分析失败:', error);
            this.updateStatus('频谱分析失败', 'error');
        } finally {
            this.analyzeBtn.disabled = false;
        }
    }

    async exportSpectrum() {
        if (!this.audioBuffer && !this.cachedSpectrumData) {
            this.updateStatus('没有可导出的频谱数据', 'error');
            return;
        }

        this.updateStatus('正在导出频谱文件...', 'loading');
        this.exportBtn.disabled = true;

        try {
            let blob;
            
            if (this.cachedSpectrumData) {
                // 使用现有的缓存数据
                const spectrumData = {
                    version: 1,
                    frameCount: this.cachedSpectrumData.length,
                    frameSize: 1024,
                    sampleRate: this.audioBuffer?.sampleRate || 44100,
                    frames: this.cachedSpectrumData,
                    metadata: {
                        duration: this.audioBuffer?.duration || 0,
                        exportedAt: new Date().toISOString()
                    }
                };
                
                const format = 'binary';
                const compression = this.compressionTypeSelect.value;
                
                if (format === 'binary') {
                    blob = this.createBinarySpectrumFile(spectrumData, compression);
                } else {
                    blob = this.createJSONSpectrumFile(spectrumData, compression);
                }
            } else {
                // 生成新的频谱数据
                const format = 'binary';
                const compression = this.compressionTypeSelect.value;
                blob = await this.generateSpectrumFile(this.audioBuffer, format, compression);
            }
            
            // 下载文件
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `spectrum_${Date.now()}.bin`;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
            
            this.updateStatus('频谱文件导出成功！', 'success');
            
        } catch (error) {
            console.error('导出失败:', error);
            this.updateStatus('导出失败', 'error');
        } finally {
            this.exportBtn.disabled = false;
        }
    }

    startVisualization() {
        const draw = () => {
            if (!this.isPlaying) return;

            // 更新进度条
            if (this.isStreamMode && this.audioElement) {
                const progress = (this.audioElement.currentTime / this.audioElement.duration) * 100;
                this.progressBar.style.width = `${Math.min(100, progress || 0)}%`;
                this.currentTime = this.audioElement.currentTime;
            } else if (this.audioBuffer) {
                this.currentTime = this.audioContext.currentTime - this.startTime;
                const progress = (this.currentTime / this.audioBuffer.duration) * 100;
                this.progressBar.style.width = `${Math.min(100, progress)}%`;
            }

            // 获取实时频谱数据
            if (this.analyser) {
                this.analyser.getByteFrequencyData(this.frequencyData);
            }

            // 绘制可视化
            this.drawVisualization();

            this.animationId = requestAnimationFrame(draw);
        };

        draw();
    }

    drawVisualization() {
        const canvas = this.canvas;
        const ctx = this.ctx;
        const width = canvas.width / window.devicePixelRatio;
        const height = canvas.height / window.devicePixelRatio;

        ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
        ctx.fillRect(0, 0, width, height);

        if (!this.frequencyData && !this.cachedSpectrumData) return;

        const barCount = 128;
        const barWidth = width / barCount;

        // 使用缓存或外部频谱数据增强可视化
        if (this.cachedSpectrumData) {
            const frameRate = this.audioBuffer ? 
                this.audioBuffer.sampleRate / 512 : 
                44100 / 512; // 默认帧率
            const frameIndex = Math.floor(this.currentTime * frameRate);
            
            if (frameIndex >= 0 && frameIndex < this.cachedSpectrumData.length) {
                const cachedFrame = this.cachedSpectrumData[frameIndex];
                this.drawEnhancedVisualization(cachedFrame, this.frequencyData || new Uint8Array(1024), barWidth, height);
            } else {
                this.drawBasicVisualization(this.frequencyData || new Uint8Array(1024), barWidth, height);
            }
        } else {
            this.drawBasicVisualization(this.frequencyData || new Uint8Array(1024), barWidth, height);
        }
    }

    drawBasicVisualization(frequencyData, barWidth, height) {
        const ctx = this.ctx;
        const barCount = 128;

        for (let i = 0; i < barCount; i++) {
            const value = frequencyData[i] || 0;
            const barHeight = (value / 255) * height * 0.8;

            const gradient = ctx.createLinearGradient(0, height, 0, height - barHeight);
            gradient.addColorStop(0, `hsl(${240 + (i / barCount) * 120}, 100%, 50%)`);
            gradient.addColorStop(1, `hsl(${240 + (i / barCount) * 120}, 100%, 70%)`);

            ctx.fillStyle = gradient;
            ctx.fillRect(i * barWidth, height - barHeight, barWidth - 1, barHeight);

            ctx.shadowColor = `hsl(${240 + (i / barCount) * 120}, 100%, 50%)`;
            ctx.shadowBlur = 10;
            ctx.fillRect(i * barWidth, height - barHeight, barWidth - 1, barHeight);
            ctx.shadowBlur = 0;
        }
    }

    drawEnhancedVisualization(cachedFrame, realtimeData, barWidth, height) {
        const ctx = this.ctx;
        const barCount = 128;

        for (let i = 0; i < barCount; i++) {
            const realtimeValue = realtimeData[i] || 0;
            const cachedValue = cachedFrame[i] || 0;
            
            const combinedValue = Math.max(realtimeValue, cachedValue * 0.7);
            const barHeight = (combinedValue / 255) * height * 0.8;

            const intensity = combinedValue / 255;
            const hue = 240 + (i / barCount) * 120 + intensity * 60;
            const saturation = 100;
            const lightness = 50 + intensity * 30;

            const gradient = ctx.createLinearGradient(0, height, 0, height - barHeight);
            gradient.addColorStop(0, `hsl(${hue}, ${saturation}%, ${lightness}%)`);
            gradient.addColorStop(0.5, `hsl(${hue}, ${saturation}%, ${lightness + 20}%)`);
            gradient.addColorStop(1, `hsl(${hue}, ${saturation}%, ${lightness + 40}%)`);

            ctx.fillStyle = gradient;
            ctx.fillRect(i * barWidth, height - barHeight, barWidth - 1, barHeight);

            // 粒子效果
            if (intensity > 0.5) {
                for (let j = 0; j < 3; j++) {
                    const particleY = height - barHeight - Math.random() * 50;
                    const particleX = i * barWidth + Math.random() * barWidth;
                    const particleSize = Math.random() * 3 + 1;
                    
                    ctx.fillStyle = `hsla(${hue}, 100%, 80%, ${0.5 + Math.random() * 0.5})`;
                    ctx.beginPath();
                    ctx.arc(particleX, particleY, particleSize, 0, Math.PI * 2);
                    ctx.fill();
                }
            }

            // 发光效果
            ctx.shadowColor = `hsl(${hue}, 100%, 60%)`;
            ctx.shadowBlur = 15 * intensity;
            ctx.fillStyle = gradient;
            ctx.fillRect(i * barWidth, height - barHeight, barWidth - 1, barHeight);
            ctx.shadowBlur = 0;
        }
    }

    stopVisualization() {
        if (this.animationId) {
            cancelAnimationFrame(this.animationId);
            this.animationId = null;
        }
        
        this.ctx.clearRect(0, 0, this.canvas.width / window.devicePixelRatio, this.canvas.height / window.devicePixelRatio);
    }

    updatePerformanceInfo() {
        const quality = this.qualityLevelSelect.value;
        const compression = this.compressionTypeSelect.value;
        const webWorker = this.useWebWorkerSelect.value === 'true';
        
        this.performanceInfo.innerHTML = `
            <strong>⚙️ 当前设置：</strong><br>
            🎯 质量: ${quality.toUpperCase()}<br>
            🗜️ 压缩: ${compression.toUpperCase()}<br>
            ⚡ Web Worker: ${webWorker ? '启用' : '禁用'}
        `;
    }

    resetAnalyzer() {
        this.stop();
        this.audioBuffer = null;
        this.audioElement = null;
        this.cachedSpectrumData = null;
        this.externalSpectrumData = null;
        this.isStreamMode = false;
        
        this.playBtn.disabled = true;
        this.pauseBtn.disabled = true;
        this.stopBtn.disabled = true;
        this.analyzeBtn.disabled = true;
        this.exportBtn.disabled = true;
        
        this.fileInfo.innerHTML = '';
        this.progressBar.style.width = '0%';
    }

    updateStatus(message, type = 'normal') {
        this.status.innerHTML = message;
        this.status.className = type;
    }

    // 重写父类方法
    onRealtimeSpectrum(frequencyData, timestamp) {
        // 流媒体实时频谱回调
        this.frequencyData = frequencyData;
    }

    onSpectrumReady(spectrum, timestamp) {
        // Web Worker计算完成回调
        // 可以在这里实现实时缓存
    }

    // 添加FFT方法（从原始script.js复制）
    fft(signal) {
        const N = signal.length;
        if (N <= 1) return signal;

        const even = [];
        const odd = [];
        for (let i = 0; i < N; i++) {
            if (i % 2 === 0) {
                even.push(signal[i]);
            } else {
                odd.push(signal[i]);
            }
        }

        const evenFFT = this.fft(even);
        const oddFFT = this.fft(odd);

        const result = new Array(N);
        for (let k = 0; k < N / 2; k++) {
            const t = {
                real: Math.cos(-2 * Math.PI * k / N) * oddFFT[k].real - Math.sin(-2 * Math.PI * k / N) * oddFFT[k].imag,
                imag: Math.sin(-2 * Math.PI * k / N) * oddFFT[k].real + Math.cos(-2 * Math.PI * k / N) * oddFFT[k].imag
            };

            result[k] = {
                real: evenFFT[k].real + t.real,
                imag: evenFFT[k].imag + t.imag
            };

            result[k + N / 2] = {
                real: evenFFT[k].real - t.real,
                imag: evenFFT[k].imag - t.imag
            };
        }

        return result;
    }

    getSpectrum(timeData) {
        const fftSize = 2048;
        const input = new Array(fftSize);
        
        for (let i = 0; i < fftSize; i++) {
            input[i] = {
                real: i < timeData.length ? timeData[i] : 0,
                imag: 0
            };
        }

        // 汉宁窗
        for (let i = 0; i < fftSize; i++) {
            const windowValue = 0.5 * (1 - Math.cos(2 * Math.PI * i / (fftSize - 1)));
            input[i].real *= windowValue;
        }

        const fftResult = this.fft(input);
        const spectrum = new Array(fftSize / 2);
        
        for (let i = 0; i < fftSize / 2; i++) {
            const real = fftResult[i].real;
            const imag = fftResult[i].imag;
            spectrum[i] = Math.sqrt(real * real + imag * imag);
        }

        return spectrum;
    }
}

// 初始化应用
document.addEventListener('DOMContentLoaded', () => {
    const analyzer = new EnhancedAudioAnalyzer();
    analyzer.updatePerformanceInfo();
});
